package com.chuangke.config;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;

/**
 * 缓存配置信息
 * 
 * @author admin
 *
 */
@Configuration
public class CacheConfig {

	public static final Map<String, String> CACHE_KEY_MAP = new HashMap<>();

	// CACHE_KEY_MAP.put("类名", "缓存key值");
	static {
		CACHE_KEY_MAP.put("BudgetAccountServiceImpl1", "budget_account111");
		CACHE_KEY_MAP.put("QhseActionService", "qhse_action");
	}

	@Autowired
	private RedisConnectionFactory redisConnectionFactory;
	/**
	 * 配置缓存的序列化方式
	 * 
	 * @return
	 */
	@ConditionalOnProperty(value="spring.cache.type",havingValue = "redis")
	@Bean
	public CacheManager redisCacheManager() {
		RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
				.serializeKeysWith(
						RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
				.serializeValuesWith(RedisSerializationContext.SerializationPair
						.fromSerializer(null));
		return RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(config).build();
	}

	@Bean
	@ConditionalOnProperty(value="spring.cache.type",havingValue = "caffeine")
	public CacheManager caffeineCacheManager() {
		CaffeineCacheManager cacheManager = new CaffeineCacheManager();
		cacheManager.setCaffeine(Caffeine.newBuilder()
				// 设置过期时间
				.expireAfterAccess(5, TimeUnit.MINUTES)
				// 设置初始化容量
				.initialCapacity(10)
				// 设置最大容量
				.maximumSize(100));
		return cacheManager;
	}

	@Bean
	public Cache<String, Object> jwtCache() {
		return Caffeine.newBuilder()
//				// 设置最后一次写入或访问后经过固定时间过期
//				.expireAfterAccess(30, TimeUnit.MINUTES)
				// 初始的缓存空间大小
				.initialCapacity(100)
				// 缓存的最大条数
				.maximumSize(9999).build();
	}

	@Bean("commonCacheKeyGenerator")
	public KeyGenerator keyGenerator() {
		return (target, method, params) -> CACHE_KEY_MAP.getOrDefault(target.getClass().getSimpleName(), getDefaultKey(target, method, params));
	}

	private String getDefaultKey(Object target, Method method, Object... params) {
		StringBuilder sb = new StringBuilder();
		sb.append(target.getClass().getName());
		return sb.toString();
	}

}
